package com.apobates.forum.grief.function;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * 将递进的语句改为并行的
 * @param <T>
 * @author xiaofanku@live.cn
 * @since 20210901
 */
public class EffectiveResult<T> {
    private final Predicate<T> condition;
    private final T data;

    /**
     *
     * @param condition 递进的判断条件
     * @param data 结果
     */
    private EffectiveResult(Predicate<T> condition, T data) {
        this.condition = condition;
        this.data = data;
    }

    private T getData() {
        return data;
    }

    /**
     * 结果是否有效.判断是否继续下一步的标记
     * @return
     */
    private boolean isEffective(){
        return null != getData();
    }

    /**
     * 设置递进的条件
     * @param condition 使用结果作为谓词函数的输入项
     * @param <T>
     * @return
     */
    public static <T> EffectiveResult<T> of(Predicate<T> condition){
        return new EffectiveResult<>(condition, null);
    }

    /**
     * 设置递进的结果
     * @param source 结果的计算函数
     * @return
     */
    public EffectiveResult<T> thenCase(Supplier<T> source){
        try {
            if (!isEffective() && condition.test(source.get())) {
                return new EffectiveResult<>(condition, source.get());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return this;
    }

    /**
     * 合并结果
     * @param source 结果的计算函数
     * @param collector 合并器
     * @return
     */
    public EffectiveResult<T> thenCollect(Supplier<T> source, EffectiveResultCollector<T> collector){
        try {
            if (condition.test(source.get())) {
                //使用哪个值
                //新值?旧值?合并(集合|字符串)
                T currentData = null;
                if(null==getData()){
                    currentData = source.get();
                }else {
                    currentData = collector.map(getData(), source.get());
                }
                return new EffectiveResult<>(condition, currentData);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return this;
    }

    /**
     * 返回结果
     * @param defaultData 结果的默认值
     * @return
     */
    public T get(T defaultData){
        return isEffective()?getData():defaultData;
    }

    /**
     * 返回结果
     * @return 若值不可用时返回null
     */
    public T get(){
        return isEffective()?getData():null;
    }

    public static void main(String[] args) {
        //测试:thenCase
        Predicate<Long> pc = (pcNum)->null!=pcNum && pcNum.compareTo(0L) ==1;
        Long rs = EffectiveResult.<Long>of(pc)
                .thenCase(()->null)
                .thenCase(() -> 2L)
                .thenCase(() -> -1L)
                .get(0L);
        System.out.println("Long="+rs.toString());
        System.out.println("------------------------------------");
        //测试:thenCollect
        Predicate<Map<String,String>> mc = (map)->null!=map && !map.isEmpty();
        Map<String,String> t1 = new HashMap<>();
        t1.put("age", "11");
        t1.put("name", "xiaofanku");

        Map<String,String> t2 = new HashMap<>();
        t2.put("age", "12");
        t2.put("name", "zhang");
        EffectiveResultCollector<Map<String,String>> mrc = (oldM,newM)->oldM;
        Map<String, String> map = EffectiveResult.of(mc)
                .thenCollect(() -> null, mrc)
                .thenCollect(() -> t1, mrc)
                .thenCollect(() -> t2, mrc)
                .get();
        map.entrySet().stream().forEach(entry-> System.out.println("key="+entry.getKey()+",val="+entry.getValue()));
    }
}
